package com.controller;

import com.service.PayService;
import com.util.UUIDUtil;
import com.util.WxPaySignatureUtils;
import io.swagger.annotations.ApiOperation;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * Created by Administrator on 2019/1/10 0010.
 */
@RequestMapping("pay")
@RestController
public class PayController {
    @Autowired
    private PayService service;

    @Bean
    public RestTemplate restTemplate() {
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }


    @ApiOperation(value = "接受支付结果")
    @PostMapping(value = "/payResult")
    @ResponseBody
    public String payResult(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("utf-8");
        StringBuffer xmlStr = new StringBuffer();
        BufferedReader reader = request.getReader();
        String line = null;
        while ((line = reader.readLine()) != null) {
            xmlStr.append(line);
        }
        String result = xmlStr.toString();
        File file = new File("C:" + File.separator + "test.txt");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        //2：准备输出流
        Writer out = new FileWriter(file);
        out.write(result);
        out.close();
        Map res = xmlString2Map(result);
        String nonceStr = (String) res.get("nonce_str");
        String transaction_id = (String) res.get("transaction_id");  //微信支付订单号
        String out_trade_no = (String) res.get("out_trade_no");    //商户订单号
        String payTime = (String) res.get("time_end");    //支付时间
        int i = service.updataPayMessage(transaction_id, out_trade_no, nonceStr, payTime);
        if (i > 0){
            return "<xml>   <return_code><![CDATA[SUCCESS]]></return_code>  <return_msg><![CDATA[OK]]></return_msg></xml>     ";
        }else{
            return "<xml>   <return_code><![CDATA[FAIL]]></return_code>  <return_msg><![CDATA订单没有交易单号]></return_msg></xml>     ";
        }
    }

    //环信
    @ApiOperation(value = "获取环信token")
    @PostMapping(value = "/getToken")
    @ResponseBody
    public String getToken() throws Exception {
        String url = "http://a1.easemob.com/1100190114042384/lyjj/token";
        Map<String,String> body = new HashMap<String,String>();
        List list = new ArrayList();
        body.put("grant_type","client_credentials");
        body.put("client_id","YXA6aUN-sB6sEemyMUeB4B7OeA");
        body.put("client_secret","YXA6kvNhY-3iHhTpGXjmSHKdMwqRwxM");
        list.add(body);
        ResponseEntity<String> responseEntity = restTemplate().postForEntity(url,body,String.class);
        return responseEntity.getBody();
    };


    @ApiOperation(value = "接受支付结果")
    @PostMapping(value = "/payResult1")
    @ResponseBody
    public String payResult1(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("utf-8");
        StringBuffer xmlStr = new StringBuffer();
        BufferedReader reader = request.getReader();
        String line = null;
        while ((line = reader.readLine()) != null) {
            xmlStr.append(line);
        }
        String result = xmlStr.toString();
        File file = new File("C:" + File.separator + "test1.txt");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        //2：准备输出流
        Writer out = new FileWriter(file);
        out.write(result);
        out.close();
        Map res = xmlString2Map(result);
        String nonceStr = (String) res.get("nonce_str");
        String transaction_id = (String) res.get("transaction_id");  //微信支付订单号
        String out_trade_no = (String) res.get("out_trade_no");    //商户订单号
        String payTime = (String) res.get("time_end");    //支付时间
        int i = service.updataRewardMsg(transaction_id, out_trade_no, nonceStr, payTime);
        if (i > 0){
            return "<xml>   <return_code><![CDATA[SUCCESS]]></return_code>  <return_msg><![CDATA[OK]]></return_msg></xml>     ";
        }else{
            return "<xml>   <return_code><![CDATA[FAIL]]></return_code>  <return_msg><![CDATA订单没有交易单号]></return_msg></xml>     ";
        }
    }

    @ApiOperation(value = "接受支付结果")
    @PostMapping(value = "/payResult2")
    @ResponseBody
    public String payResult2(HttpServletRequest request, HttpServletResponse response) throws Exception {
        request.setCharacterEncoding("utf-8");
        StringBuffer xmlStr = new StringBuffer();
        BufferedReader reader = request.getReader();
        String line = null;
        while ((line = reader.readLine()) != null) {
            xmlStr.append(line);
        }
        String result = xmlStr.toString();
        File file = new File("C:" + File.separator + "test2.txt");
        if (!file.getParentFile().exists()) {
            file.getParentFile().mkdirs();
        }
        //2：准备输出流
        Writer out = new FileWriter(file);
        out.write(result);
        out.close();
        Map res = xmlString2Map(result);
        String nonceStr = (String) res.get("nonce_str");
        String transaction_id = (String) res.get("transaction_id");  //微信支付订单号
        String out_trade_no = (String) res.get("out_trade_no");    //商户订单号
        String payTime = (String) res.get("time_end");    //支付时间
        int i = service.updataRechargeMsg(transaction_id, out_trade_no, nonceStr, payTime);
        if (i > 0){
            return "<xml>   <return_code><![CDATA[SUCCESS]]></return_code>  <return_msg><![CDATA[OK]]></return_msg></xml>     ";
        }else{
            return "<xml>   <return_code><![CDATA[FAIL]]></return_code>  <return_msg><![CDATA订单没有交易单号]></return_msg></xml>     ";
        }
    }
    //以下为支付所需接口和函数
    @ApiOperation(value = "支付")
    @PostMapping(value = "/pay")
    @ResponseBody
    public Map pay(HttpServletRequest request, Integer userId,String price,Integer type) throws Exception {
        request.setCharacterEncoding("utf-8");
        String uuid = UUIDUtil.get32UUID();
//        String openid = service.findOpenId(userId,price,type,uuid);
        String openid = service.findNewOpenId(userId,price,type,uuid);
        System.out.println(openid);
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        Map<String, String> map = new TreeMap<String, String>();
        map.put("appid", "wx5753938128c05c02");
        map.put("body", "lyjj-CoursePurchase");
        map.put("mch_id", "1519287851");
        map.put("nonce_str", uuid); // 随机串
        System.out.println(uuid);
        if(type == 1){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult");// 通知URL地址
        }else if(type == 2){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult1");// 通知URL地址
        }else if(type == 3){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult2");// 通知URL地址
        }
        map.put("openid", openid);// 用户微信唯一标识
        String time = String.valueOf(Calendar.getInstance().getTimeInMillis());
        map.put("out_trade_no", time);//此参数填写订单的时间戳
        String ip = findIP(request);
        map.put("spbill_create_ip", ip); //用户端的IP地址
        map.put("total_fee", price);// 此参数为订单金额
        map.put("trade_type", "JSAPI");
        String str = WxPaySignatureUtils.signature(map, "yutongkejilingyingjiajiao2018100");
        System.out.println(str);
        map.put("sign", str); //签名
        System.out.println(map2xml(map));
        ResponseEntity<String> responseEntity =
                restTemplate().postForEntity(url, map2xml(map), String.class);
        System.out.println("pay" + responseEntity.getBody());
        Map m = xmlString2Map(responseEntity.getBody());
        Map<String, String> map2 = new TreeMap<String, String>();
        map2.put("appId", "wx5753938128c05c02");
        map2.put("nonceStr", uuid);
        System.out.println(m.get("prepay_id"));
        map2.put("package", "prepay_id=" + m.get("prepay_id"));
        map2.put("signType", "MD5");
        map2.put("timeStamp", time);
        String twoSign = WxPaySignatureUtils.signature(map2, "yutongkejilingyingjiajiao2018100");
        map2.put("paySign", twoSign);
        return map2;
    }


    @ApiOperation(value = "家长端支付")
    @PostMapping(value = "/payStudent")
    @ResponseBody
    public Map payStudent(HttpServletRequest request, Integer userId,String price,Integer type) throws Exception {
        request.setCharacterEncoding("utf-8");
        String uuid = UUIDUtil.get32UUID();
//        String openid = service.findOpenId(userId,price,type,uuid);
//        String openid = "oZrVK5Oub0tu30DJvQsHGWggzbww";
        String openid = service.findNewOpenId(userId,price,type,uuid);
        System.out.println(openid);
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        Map<String, String> map = new TreeMap<String, String>();
        map.put("appid", "wxfe414ab7903ae4f8");
        map.put("body", "lyjj-CoursePurchase");
        map.put("mch_id", "1519287851");
        map.put("nonce_str", uuid); // 随机串
        System.out.println(uuid);
        if(type == 1){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult");// 通知URL地址
        }else if(type == 2){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult1");// 通知URL地址
        }else if(type == 3){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult2");// 通知URL地址
        }
        map.put("openid", openid);// 用户微信唯一标识
        String time = String.valueOf(Calendar.getInstance().getTimeInMillis());
        map.put("out_trade_no", time);//此参数填写订单的时间戳
        String ip = findIP(request);
        map.put("spbill_create_ip", ip); //用户端的IP地址
        map.put("total_fee", price);// 此参数为订单金额
        map.put("trade_type", "JSAPI");
        String str = WxPaySignatureUtils.signature(map, "yutongkejilingyingjiajiao2018100");
        System.out.println(str);
        map.put("sign", str); //签名
        System.out.println(map2xml(map));
        ResponseEntity<String> responseEntity =
                restTemplate().postForEntity(url, map2xml(map), String.class);
        System.out.println("pay" + responseEntity.getBody());
        Map m = xmlString2Map(responseEntity.getBody());
        Map<String, String> map2 = new TreeMap<String, String>();
        map2.put("appId", "wxfe414ab7903ae4f8");
        map2.put("nonceStr", uuid);
        System.out.println(m.get("prepay_id"));
        map2.put("package", "prepay_id=" + m.get("prepay_id"));
        map2.put("signType", "MD5");
        map2.put("timeStamp", time);
        String twoSign = WxPaySignatureUtils.signature(map2, "yutongkejilingyingjiajiao2018100");
        map2.put("paySign", twoSign);
        return map2;
    }

    @ApiOperation(value = "老师端支付")
    @PostMapping(value = "/payTeacher")
    @ResponseBody
    public Map payTeacher(HttpServletRequest request, Integer userId,String price,Integer type) throws Exception {
        request.setCharacterEncoding("utf-8");
        String uuid = UUIDUtil.get32UUID();
//        String openid = service.findOpenId(userId,price,type,uuid);
//        String openid = "oZrVK5Oub0tu30DJvQsHGWggzbww";
        String openid = service.findNewOpenId(userId,price,type,uuid);
        System.out.println(openid);
        String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        Map<String, String> map = new TreeMap<String, String>();
        map.put("appid", "wx8a7b9ecd1ce7704b");
        map.put("body", "lyjj-CoursePurchase");
        map.put("mch_id", "1519287851");
        map.put("nonce_str", uuid); // 随机串
        System.out.println(uuid);
        if(type == 1){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult");// 通知URL地址
        }else if(type == 2){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult1");// 通知URL地址
        }else if(type == 3){
            map.put("notify_url", "https://www.auriakj.com/lyjj2/pay/payResult2");// 通知URL地址
        }
        map.put("openid", openid);// 用户微信唯一标识
        String time = String.valueOf(Calendar.getInstance().getTimeInMillis());
        map.put("out_trade_no", time);//此参数填写订单的时间戳
        String ip = findIP(request);
        map.put("spbill_create_ip", ip); //用户端的IP地址
        map.put("total_fee", price);// 此参数为订单金额
        map.put("trade_type", "JSAPI");
        String str = WxPaySignatureUtils.signature(map, "yutongkejilingyingjiajiao2018100");
        System.out.println(str);
        map.put("sign", str); //签名
        System.out.println(map2xml(map));
        ResponseEntity<String> responseEntity =
                restTemplate().postForEntity(url, map2xml(map), String.class);
        System.out.println("pay" + responseEntity.getBody());
        Map m = xmlString2Map(responseEntity.getBody());
        Map<String, String> map2 = new TreeMap<String, String>();
        map2.put("appId", "wx8a7b9ecd1ce7704b");
        map2.put("nonceStr", uuid);
        System.out.println(m.get("prepay_id"));
        map2.put("package", "prepay_id=" + m.get("prepay_id"));
        map2.put("signType", "MD5");
        map2.put("timeStamp", time);
        String twoSign = WxPaySignatureUtils.signature(map2, "yutongkejilingyingjiajiao2018100");
        map2.put("paySign", twoSign);
        return map2;
    }

    public static String map2xml(Map<String, String> map) throws Exception {
        StringBuffer sb = new StringBuffer("");
        sb.append("<xml>");
        Set<String> set = map.keySet();
        for (Iterator<String> it = set.iterator(); it.hasNext(); ) {
            String key = it.next();
            Object value = map.get(key);
            if (!key.equals("sign")) {
                sb.append("<").append(key).append(">").append("<![CDATA[");
                sb.append(value);
                sb.append("]]>").append("</").append(key).append(">");
            } else {
                sb.append("<").append(key).append(">");
                sb.append(value);
                sb.append("</").append(key).append(">");
            }
        }
        sb.append("</xml>");
        return sb.toString();

    }

    public static Map<String, Object> xmlString2Map(String xmlStr) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        Document doc = DocumentHelper.parseText(xmlStr);
        Element el = doc.getRootElement();
        map = recGetXmlElementValue(el, map);
        return map;
    }

    @SuppressWarnings({"unchecked"})
    private static Map<String, Object> recGetXmlElementValue(Element ele, Map<String, Object> map) {
        List<Element> eleList = ele.elements();
        if (eleList.size() == 0) {
            map.put(ele.getName(), ele.getTextTrim());
            return map;
        } else {
            for (Iterator<Element> iter = eleList.iterator(); iter.hasNext(); ) {
                Element innerEle = iter.next();
                recGetXmlElementValue(innerEle, map);
            }
            return map;
        }
    }

    //查询客户端IP地址。
    public static String findIP(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    //以上为支付所需接口
}
